
// Define the global namespace for the application and the functions/methods within it (in case it's not already set)
if (!window.FrontSuite) FrontSuite = {};
if (!FrontSuite.util) FrontSuite.util = {};

// This turns a password into a hash so that the password itself never leaves the client machine.
// It does leave the client machine encrypted at the time of registration.
// However at authentication time, it gets hashed again to become an auth_token (see makeAuthToken() below).
// TODO: Pay attention to the algorithm and algorithm_option instead of making assumptions.
FrontSuite.util.makePasswordHash = function (algorithm, algorithm_option, password, user_salt) {
    // var password_hash = sjcl.codec.hex.fromBits(sjcl.misc.pbkdf2(password, sjcl.codec.utf8String.toBits(user_salt), 16384)); // takes a significant fraction of a second to compute
    var password_hash = sjcl.codec.hex.fromBits(sjcl.misc.pbkdf2(password, sjcl.codec.utf8String.toBits(user_salt), algorithm_option)); // takes a significant fraction of a second to compute
    return(password_hash);
}
// An auth_token is made up of a hash of the password_hash, the session_expire_dttm, and the client_connection_token (remote_addr + http_user_agent).
// Thus, auth_token's expire, and are also of no value to an attacker who is not coming from the required remote_addr.
// The username, the auth_token, and the session_expire_dttm are passed on to the server for authentication on each trip to the server.
// TODO: Make allowance for changing client_connection_token (remote_addr + http_user_agent)
FrontSuite.util.makeAuthToken = function (password_hash, session_expire_dttm, client_connection_token) {
    var auth_token    = sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(password_hash + '|' + session_expire_dttm + '|' + client_connection_token));
    return(auth_token);
}
// TODO. For some reason, I couldn't yet get this routine to do exactly what the respective server routine does.
FrontSuite.util.encrypt = function (secret_key, data) {
    // var encrypted_data = sjcl.encrypt(secret_key, data);
    var encrypted_data = data;
    return(encrypted_data);
}
// TODO. For some reason, I couldn't yet get this routine to do exactly what the respective server routine does.
FrontSuite.util.decrypt = function (secret_key, encrypted_data) {
    // var data = sjcl.decrypt(secret_key, encrypted_data);
    var data = encrypted_data;
    return(data);
}
// The user interface code calls this function with any of a list of permission strings to see if the current user is authorized to see or perform something.
// This function is very efficient and makes no calls to the server.
// The "perm" (permission) strings are hierarchical as illustrated below. The code asks "am I authorized?" at the detail level.
// The permission may be granted or denied explicitly at any level at or above the detail level.
//      "perm"                              - meaning
// e.g. "/api"                              - Am I authorized to invoke the server-api at all?
//      "/api/object/auth"                  - Am I authorized to invoke the server-api for any tables on the "auth" database?
//      "/api/object/auth/_write"           - Am I authorized to invoke the server-api to modify any tables on the "auth" database?
//      "/api/object/auth/auth_user"        - Am I authorized to invoke the server-api for the auth_user table on the "auth" database?
//      "/api/object/auth/auth_user/select" - Am I authorized to invoke the server-api to select rows from the auth_user table on the "auth" database?
//      "/api/object/auth/auth_user/insert" - Am I authorized to invoke the server-api to insert rows into the auth_user table on the "auth" database?
//      "/api/object/auth/auth_user/update" - Am I authorized to invoke the server-api to update rows in   the auth_user table on the "auth" database?
//      "/api/object/auth/auth_user/delete" - Am I authorized to invoke the server-api to delete rows from the auth_user table on the "auth" database?
//      "/api/object/_phys"                 - Am I authorized to invoke the server-api for specific physical tables?
//      "/api/service/auth"                 - Am I authorized to invoke the server-api for any of the services in the "auth" package?
//      "/api/service/auth/login"           - Am I authorized to invoke the server-api for the login service in the "auth" package?
//      "/app/dbfront"                      - Am I authorized to do anything in the "dbfront" application?
//      "/app/dbfront/menu/admin"           - Am I authorized to access the "admin" menu in the "dbfront" application?
//      "/app/dbfront/menu/admin/groups"    - Am I authorized to access the "groups" menu item in the admin menu in the "dbfront" application?
//      "/app/dbfront/view/group-admin"     - Am I authorized to use the "group-admin" view in the "dbfront" application?
//      "/app/dbfront/view/group-admin/new" - Am I authorized to use the "new" button on the "group-admin" view in the "dbfront" application?
FrontSuite.util.isAuthorized = function (perm) {
    var authorized = 0;
    if (FrontSuite.session && FrontSuite.session.authdata && FrontSuite.session.authdata.perms) {
        var perms = FrontSuite.session.authdata.perms;
        if (perm == '') perm = '/';
        if (perms[perm] !== undefined) {
            authorized = perms[perm];
        }
        else if (perm === '/') {
            authorized = 0;
        }
        else {
            var parent_perm = perm.replace(/\/[^/]+$/,'');
            if (perm !== parent_perm) {
                authorized = FrontSuite.util.isAuthorized(parent_perm);
                perms[perm] = authorized;  // save the result for next time
            }
        }
    }
    return(authorized);
}

